﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;

////多态是⼀个继承关系的下的类对象，去调⽤同⼀函数，产⽣了不同的⾏为。⽐如Student继承了
////Person。Person对象买票全价，Student对象优惠买票
////实现多态的几个重要条件
////1.在继承之下
////2.必须是父类的引用调用或者是指针
////3.被调用的函数必须是虚函数
//class Person
//{
//public:
//	virtual void Buy_Ticket()
//	{
//		cout << "全价" << endl;
//	}
//};
//
//class Student:public Person
//{
//public:
//	virtual void Buy_Ticket()//虚函数有三同 返回类型相同 函数名相同参数相同
//	{
//		cout << "半价" << endl;
//	}
//};
////非成员函数不能加virtual修饰
//
////void func(Person*st)
////{
////	st->Buy_Ticket();
////}
////传过来的必须是指针或者是引用
//void func(Person& st)
//{
//	st.Buy_Ticket();
//}
//int main()
//{
//	Person p;
//	Student s;
//	func(p);
//	func(s);
//	//必须是父类的指针或者是引用去调用这个虚函数才能万和完成多态
//	//因为只有父类的引用或者是指针才能调到子类和父类
//	//在子类里面对这个函数完成重写和覆盖
//	//子类可以不写virtual关键字，可以继承父类的也构成重写，但是父类的必须写，但不建议这样写，不规范
//	Person& v = p;
//	v.Buy_Ticket();
//	return 0;
//}
//


//class Animal
//{
//public:
//	virtual void talk()
//	{};
//};
//
//class Dog:public Animal
//{
//public:
//	virtual void talk()
//	{
//		cout << "旺旺!" << endl;
//	}
//};
//
//class Cat : public Animal
//{
//public:
//	virtual void talk()
//	{
//		cout << "喵喵！" << endl;
//	}
//};
//
//int main()
//{
//	Dog *dog=new Dog;
//	Cat *cat=new Cat;
//	dog->talk();
//	cat->talk();
//	return 0;
//}

//class A
//{
//public:
//	virtual void func(int a = 1)
//	{
//		cout << "A->" << a << endl;
//	}
//	void test()
//	{
//		func();
//	}
//}; 
//
//class B:public A
//{
//public:
//	virtual void func(int a = 0)
//	{
//		cout << "B->" << a << endl;
//	}
//};
//
//int main()
//{
//	B* b = new B;
//	b->test();//子类只是对父类完成重写，并没有改动函数的三个要素
//	b->func();
//	return 0;
//}


//协变 父类返回父类的指针或引用 子类返回子类的指或引用 
//class Person
//{
//public:
//	virtual Person* func()
//	{
//		cout << "Person 全价" << endl;
//		return this;
//	}
//};
//
//class Student :public Person
//{
//public:
//	virtual Student* func()
//	{
//		cout << "student 半价" << endl;
//		return this;
//	}
//};
//
//int main()
//{
//	Person* p = new Person;
//	Student* s = new Student;
//	p->func();
//	s->func();
//	return 0;
//}

//对虚函数的重写，虚函数会被处理为destroy然后需要在
//class A
//{
//public:
//	 ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//
//class B :public A
//{
//public:
//	~B()
//	{
//		cout << "~B()" << endl;
//		delete[] _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//
//int main()
//{
//	A* a = new A;
//	A* b = new B;
//	delete a;
//	delete b;
//	return 0;
//}
//class A
//{
//public:
//	virtual ~A()
//	{
//		cout << "~A()" << endl;
//	}
//};
//class B : public A {
//public:
//	~B()
//	{
//		cout << "~B()->delete:" << _p << endl;
//		delete _p;
//	}
//protected:
//	int* _p = new int[10];
//};
//int main()
//{
//	A* p1 = new A;
//	A* p2 = new B;
//	delete p1;
//	delete p2;
//	return 0;
//}

//override和final
//override帮助我们检查这个函数是否重写对，避免后续我们屋调试检查
//final让这个函数不能被子类重写

//class Car
//{
//public:
//	virtual void Dire()
//	{
//		cout << "Dire()" << endl;
//	}
//	virtual void a()//final
//	{
//		cout << "a()" << endl;
//	}
//};
//class Benz:public Car
//{
//public:
//	virtual void Dire()override//自动帮我们检查这个函数是否拼写正确
//	{
//		cout << "舒适" << endl;
//	}
//	virtual void a()//父类这个函数有final修饰在子类中我们不能对他进行重写
//	{
//		cout << "benz" << endl;
//	}
//};
//
//int main()
//{
//	Car* bn = new Benz;
//	bn->Dire();
//	return 0;
//}

//纯虚函数和抽象类
//纯虚函数只需要在虚函数后加上=0;纯虚函数可以定义实现但是，没有必要因为他要被派生类重写，所以只需要声明即可
//抽象类，包含纯虚函数的类叫抽象类，抽象类不能实例化出对象，所以纯虚函数才要注定被派生类重写不然派生类也不能实例化出对象

//class Car
//{
//public:
//	virtual void Dire() = 0;
//};
//
//class Benz :public Car
//{
//public:
//	virtual void Dire()override
//	{
//		cout << "舒适" << endl;
//	}
//};
//
//class BWM :public Car
//{
//public:
//	virtual void Dire()override
//	{
//		cout << "操控" << endl;
//	}
//};
//
//int main()
//{
//	//Car car;//抽象类不能实例出对象
//	Car* benz = new Benz;
//	benz->Dire();
//
//	Car* bwm = new BWM;
//	bwm->Dire();
//
//	return 0;
//}


//多态实现的原理
//class Base
//{
//public:
//    virtual void  func()
//    {
//        cout << "func()" << endl;
//    }
//    //虚函数放在虚函数表中，虚函数表是一个二级指针数组存放函数指针
//    // 一个类有虚函数那么就会有虚函数表，虚函数存在这个表里方便后续找到虚函数的地址
//protected:
//    int _a = 1;
//    char _x = 'x';
//};
//
//int main()
//{
//    Base b;
//    cout << sizeof(b) << endl;
//    return 0;
//}

//class Person
//{
//public:
//	virtual void BuyTicket()
//	{
//		cout << "全价" << endl;
//	}
//protected:
//	string _name;
//};
//
//class Student :public Person
//{
//public:
//	virtual void BuyTicket()override
//	{
//		cout << "半价" << endl;
//	}
//protected:
//	int _id;
//};
//
//class Soldier :public Person
//{
//public:
//	virtual void BuyTicket()override
//	{
//		cout << "优先" << endl;
//	}
//protected:
//	string _code;//代号
//};
//int main()
//{
//	Person* p = new Person;
//	Person* s = new Student;
//	Person* so = new Soldier;
//	p->BuyTicket();
//	s->BuyTicket();
//	so->BuyTicket();
//	//他们有各自的虚函数表，都是对对应的虚函数进行重写，不管你传谁，看到的都只是父类的切片，但是这是的虚函数表里存放的是这个对象的重写后的虚函数
//	//所以做到了指向谁调用谁
//	return 0;
//}
//同类的虚表共用，不同类的各自独立

class Base {
public:
	virtual void func1() { cout << "Base::func1" << endl; }
	virtual void func2() { cout << "Base::func2" << endl; }
	void func5() { cout << "Base::func5" << endl; }
protected:
	int a = 1;
};
class Derive : public Base
{
public:
	// 重写基类的func1
	virtual void func1() { cout << "Derive::func1" << endl; }
	virtual void func3() { cout << "Derive::func1" << endl; }
	void func4() { cout << "Derive::func4" << endl; }
protected:
	int b = 2;
};
//int main()
//{
//	Base b;
//	Derive d;
//	return 0;
//}

int main()
{
	int i = 0;
	static int j = 1;
	int* p1 = new int;
	const char* p2 = "xxxxxxxx";
	printf("栈:%p\n", &i);
	printf("静态区:%p\n", &j);
	printf("堆:%p\n", p1);
	printf("常量区:%p\n", p2);

	Base b;
	Derive d;
	Base* p3 = &b;
	Derive* p4 = &d;
	printf("Person虚表地址:%p\n", *(int*)p3);//找到这个虚函数表，取头上的四个字节
	printf("Student虚表地址:%p\n", *(int*)p4);
	printf("虚函数地址:%p\n", &Base::func1);
	printf("普通函数地址:%p\n", &Base::func5);
	return 0;
}